package core

import (
	"fmt"
	"strconv"
	"time"
	"zinx_websokect_poker/zinx_app/poker_game/http"
	json2 "zinx_websokect_poker/zinx_app/poker_game/json"
	"zinx_websokect_poker/zinx_app/poker_game/log"
	"zinx_websokect_poker/zinx_app/poker_game/protocol"
)

type JRR struct {
	Code         int                        `json:"code"`
	IsCreateRoom int                        `json:"isCreateRoom"`
	RoomInfo     *protocol.JoinRoomResponse `json:"roomInfo"`
	GameInfo     *protocol.GameInfo         `json:"gameInfo"`
}

func (r *Room) JoinRoom(m interface{},oi interface{},code int) {
	o := oi.(*Occupant)

	//给玩家带入记分牌
	o.chips = r.DraginChips

	userinfos := make([]*protocol.UserSeat, 0, r.Cap())
	//取出房间内坐着的玩家数据，发送给刚进入房间的玩家。
	for _, o := range r.Occupants {
		if o != nil {
			userSeat := &protocol.UserSeat{
				Name: o.Nickname,
				UserId: o.OutId,
				Avatar: o.Profile,
				Chips: o.chips,
				//CurrentChips: 1,
				IsGiveUp: false,
				IsMySelf: false,
				//Pokes:
				Position: o.Pos,
				//Level: o.
			}
			userinfos = append(userinfos, userSeat)
		}
	}

	room := &protocol.JoinRoomResponse{
		BB: r.BB,
		Chips: r.DraginChips,
		Name: r.OwnerOc.Nickname,
		//Clients:
		CreateTime:  strconv.Itoa(int(r.CreatedAt.Unix())),
		CurrentDepend: r.Button,
		CurrentPerson: r.Len(),
		//History:
		Max: r.Max,
		Owner: r.Owner,
		RoomId: r.Number,
		SB: r.SB,
		Seats: userinfos,
		State: r.status,
		Time: r.RoomTime,
		IsBegin: r.IsBeginning(),
	}
	game := &protocol.GameInfo{}
	if r.status == RUNNING{
		gameSeats := make([]*protocol.UserSeat, 0, r.Cap())
		for _, o := range r.Occupants {
			if o != nil {
				var pokes []int = nil
				var level uint8
				if cards := o.cards; cards !=nil  {
					pokes = o.cards[0:2].GetValues()
					level = cards.GetCombination().Type
				}

				userSeat := &protocol.UserSeat{
					Avatar: o.Profile,
					Chips: o.chips,
					CurrentChips: o.currentChips,
					IsGiveUp: o.IsSitdown(),
					IsLeaveRoom: false,
					IsSitUp: false,
					Level: int(level),
					Name: o.Nickname,
					Pokes: pokes,
					Position: o.Pos,
					UserId: o.OutId,
				}
				gameSeats = append(gameSeats, userSeat)
			}
		}
		var DependUserId int64 = 0
		var SbUserId int64 = 0
		if r.Occupants[r.Button - 1] != nil {
			DependUserId = r.Occupants[r.Button - 1].OutId
		}
		if r.Occupants[r.sbPos - 1] != nil {
			SbUserId = r.Occupants[r.sbPos - 1].OutId
		}
		game = &protocol.GameInfo{
			GameState: r.GameState,
			AllCount: r.getPot(),
			GameSeats: gameSeats,
			ShowPokes: r.Cards.GetValues(),
			DependUserId: DependUserId,
			SbUserId: SbUserId,
			CurrentUser: r.Current,
		}
	}else {
		game = nil
	}

	r.addObserve(o)

	log.Info("Room-JoinRoom", "【加入房间】房间号：" + r.Number +
		"房主：" + r.OwnerOc.Nickname + "OutId :" +strconv.Itoa(int(r.Owner)))
	fmt.Println("房管",r.Owner)

	o.RoomID = r.Number
	o.SetRoom(r)

	resp := &JRR{
		Code: 0,
		IsCreateRoom: code,
		RoomInfo: room,
		GameInfo: game,
	}
	//将用户所在房间更新到数据库
	http.SetUserGameId(o.OutId, r.Number)

	jsonStu := json2.Jsonmr(4, resp)

	o.WriteMsg(jsonStu)
}

func (r *Room) ReJoinRoom(oi interface{},code int){
	o := oi.(*Occupant)

	//玩家重连
	for k, v := range r.Occupants {
			//glog.Infoln(v, o)
		if v == nil {
			continue
		}
		if v.OutId == o.OutId {
			// todo 掉线重连现场数据替换处理
			o.Replace(r.Occupants[k])
			r.Occupants[k] = o
			//替换房主
			if r.OwnerOc.OutId == o.OutId {
				r.OwnerOc = o
			}
			//移除连接所属的旧的玩家数据
			OccupantMgrObj.RemoveOccupantByPid(v.Pid)
			PlayerMgrObj.RemovePlayerByPid(v.Pid)
		}
	}

	//游客重连
	for k, v := range r.observes {
			//glog.Infoln(v, o)
		if v == nil {
			continue
		}
		if v.OutId == o.OutId {
			// todo 掉线重连现场数据替换处理
			o.Replace(r.observes[k])
			r.observes[k] = o
			//替换房主
			if r.OwnerOc.OutId == o.OutId {
				r.OwnerOc = o
			}
			//移除连接所属的旧的玩家数据
			OccupantMgrObj.RemoveOccupantByPid(v.Pid)
			PlayerMgrObj.RemovePlayerByPid(v.Pid)
		}
	}

	log.Info("Room-ReJoinRoom", "【掉线重连】房间号：" + r.Number +
		"玩家：" + o.Nickname + "OutId :" +strconv.Itoa(int(o.OutId)))

	userinfos := make([]*protocol.UserSeat, 0, r.Cap())
	//取出房间内坐着的玩家数据，发送给刚进入房间的玩家。
	for _, oo := range r.Occupants {
		if oo != nil {
			userSeat := &protocol.UserSeat{
				Name: oo.Nickname,
				UserId: oo.OutId,
				Avatar: oo.Profile,
				Chips: oo.chips,
				//CurrentChips: 1,
				IsGiveUp: false,
				IsMySelf: false,
				//Pokes:
				Position: oo.Pos,
				//Level: o.
			}
			userinfos = append(userinfos, userSeat)
		}
	}

	room := &protocol.JoinRoomResponse{
		BB: r.BB,
		Chips: r.DraginChips,
		Name: r.OwnerOc.Nickname,
		//Clients:
		CreateTime:  strconv.Itoa(int(r.CreatedAt.Unix())),
		CurrentDepend: r.Button,
		CurrentPerson: r.Len(),
		//History:
		Max: r.Max,
		Owner: r.Owner,
		RoomId: r.Number,
		SB: r.SB,
		Seats: userinfos,
		State: r.status,
		Time: r.RoomTime,
		IsBegin: r.IsBeginning(),
	}
	game := &protocol.GameInfo{}
	game = nil
	if r.status == RUNNING{
		gameSeats := make([]*protocol.UserSeat, r.Cap()+1)
		for _, o := range r.Occupants {
			if o != nil {
				cards := o.cards
				pokes := o.cards[0:2]
				level := cards.GetCombination().Type
				userSeat := &protocol.UserSeat{
					Avatar: o.Profile,
					Chips: o.chips,
					CurrentChips: o.currentChips,
					IsGiveUp: o.IsSitdown(),
					IsLeaveRoom: false,
					IsSitUp: false,
					Level: int(level),
					Name: o.Nickname,
					Pokes: pokes.GetValues(),
					Position: o.Pos,
					UserId: o.OutId,
				}
				//gameSeats = append(gameSeats, userSeat)
				gameSeats[o.Pos] = userSeat
			}
		}
		var DependUserId int64 = 0
		var SbUserId int64 = 0
		if r.Occupants[r.Button - 1] != nil {
			DependUserId = r.Occupants[r.Button - 1].OutId
		}
		if r.Occupants[r.sbPos - 1] != nil {
			SbUserId = r.Occupants[r.sbPos - 1].OutId
		}
		//下注倒计时
		var times float64
		if timer := r.SecondsTimer; timer != nil {
			times = timer.TimeRemaining().Seconds()
		}
		game = &protocol.GameInfo{
			GameState: r.GameState,
			AllCount: r.getPot(),
			GameSeats: gameSeats,
			ShowPokes: r.Cards.GetValues(),
			DependUserId: DependUserId,
			SbUserId: SbUserId,
			CurrentUser: r.Current,
			Times: times,
			FollowBet: r.Bet - o.Bet,
		}
	}


	resp := &JRR{
		Code: 0,
		IsCreateRoom: code,
		RoomInfo: room,
		GameInfo: game,
	}

	jsonStu := json2.Jsonmr(4, resp)
	//重连发送进入房间的信息给玩家。
	o.WriteMsg(jsonStu)
}

func (r *Room) leaveAndRecycleChips(o *Occupant) bool{
	if r.removeOccupant(o) > 0 {
		// 玩家站起回收带入筹码
		gap := int32(o.chips) - int32(r.DraginChips)
		if gap == 0 {
			//o.UpdateChips(gap)
			fmt.Println("更新用户筹码")
		}
		return true
	}
	return false
}

func (r *Room) GetRoomInfo(oo interface{}) {
	o := oo.(*Occupant)
	room := &protocol.JoinRoomResponse{}
	if r.Owner == o.OutId {
		room = &protocol.JoinRoomResponse{
			BB: r.BB,
			Chips: r.DraginChips,
			//Clients:
			CreateTime:  strconv.Itoa(int(r.CreatedAt.Unix())),
			CurrentDepend: r.Button,
			CurrentPerson: r.Len(),
			//History:
			Max: r.Max,
			Owner: r.Owner,
			RoomId: r.Number,
			SB: r.SB,
			//Seats: userinfos,
			State: r.status,
			Time: r.RoomTime,
			Name: o.Nickname,
			//IsBegin: o.IsGameing(),
		}
	}




	var jsonStu []byte
	if room.Owner != 0 {
		jsonStu = json2.Jsonmr(6, room)
	}else {
		jsonStu = json2.Jsonmr(6, nil)
	}

	o.WriteMsg(jsonStu)

}

func (r *Room) LeaveRoom(oo interface{}) {
	o := oo.(*Occupant)
	if !o.IsObserve() {
		r.StandUp(o)
	}
	log.Info("Room-StandUp", "【离开房间】房间号：" + r.Number +
		"，玩家：" + o.Nickname + "，OutId :" +strconv.Itoa(int(o.OutId)))

	r.removeObserve(o)
	//r.removeOccupant(o)
	//r.leaveAndRecycleChips(o)
	o.RoomID = ""
	o.room = nil
	//o.UpdateRoomId()
	leave := &protocol.StandUp{
		Code: 0,
	}
	http.SetUserGameId(o.OutId, "")

	jsonStu := json2.Jsonmr(59, leave)

	o.WriteMsg(jsonStu)

	//r.Debug()
	fmt.Println("房间里的玩家人数",r.Len(),"观看人数",r.ObLen())
	// 房间里没有玩家时关闭并从列表中删除
	if r.Len() + r.ObLen() == 0 {
		//r.Close(r)
		DelRoom(r)
		http.Endgameroom(r.GetNumber())
	}
	//glog.Errorln("leaveRoom", m)
}

func (r *Room) SitDown(pos uint8, oo interface{}) {
	code := 1
	o := oo.(*Occupant)
	if pos <= 0 || pos > 9 {
		pos = 9 // default 9 Occupants
	}
	//todo 两种情况，
	//	1.玩家未坐下，将玩家放入对应位置并加入房间的玩家列表
	//	2.玩家切换位置

	//查找玩家是否已在房间内
	for k, v := range r.Occupants {
		if v != nil && v.GetPlayerid() == o.Pid {
			//查看想要切换的位置有没有人,k为玩家当前位置，pos为想要切换的位置
			if r.Occupants[pos - 1] == nil {
				r.removeObserve(o)
				r.Occupants[k], r.Occupants[pos - 1] = r.Occupants[pos - 1], r.Occupants[k]
				r.staticOccupants[k], r.staticOccupants[pos - 1] = r.staticOccupants[pos - 1], r.staticOccupants[k]
				//r.Occupants[pos - 1], r.Occupants[k] = r.Occupants[k], nil
				o.Pos = pos
				code = 0
			}
		}
	}

	//玩家从旁观坐到桌上
	if r.Occupants[pos - 1] == nil {
		r.removeObserve(o)
		r.Occupants[pos - 1] = o
		r.staticOccupants[pos - 1] = *o
		o.Pos = pos
		o.SetSitdown()
		code = 0
	}

	//pos = r.addOccupant(o)
	//if pos == 0 {
	//  给进入房间的玩家带入筹码
	//	o.chips = r.DraginChips
	//	r.addObserve(o)
	//} else {
	//
	//}


	//userInfo := &protocol.UserInfo{
	//		Nickname: o.Nickname,
	//		Uid:      o.Uid,
	//		Account:  o.Account,
	//		Sex:      o.Sex,
	//		Profile:  o.Profile,
	//		Chips:    o.chips,
	//		Pos:	  o.Pos,
	//	}

	userSeat := &protocol.UserSeat{
		Name: o.Nickname,
		UserId: o.OutId,
		Avatar: o.Profile,
		Chips: o.chips,
		//CurrentChips: 1,
		IsGiveUp: false,
		IsMySelf: false,
		//Pokes:
		Position: o.Pos,
		//Level: o.
	}

	//jsonStu := json2.Jsonmr(50, &protocol.JoinRoomBroadcast{UserInfo: userInfo})
	jsonStu := json2.Jsonmr(50, &protocol.SitDownBroadcast{
		Code: code,
		UserSeat: userSeat,
	})

	r.Broadcast(jsonStu, true)

	log.Info("Room-SitDown", "【玩家坐下】房间号：" + r.Number + "，座位号：" + strconv.Itoa(int(o.Pos)) +
		"，玩家：" + o.Nickname + "，OutId :" +strconv.Itoa(int(o.OutId)))

	//坐下开始游戏
	if r.status == GAMEOVER && r.IsBegin == BEGIN{
		time.AfterFunc(time.Second*2, func() {
			r.StartDelay(&StartDelay{})
		})
	}

}

func (r *Room) StandUp(oo interface{}) {
	o := oo.(*Occupant)

	fmt.Println("玩家站起")
	log.Info("Room-StandUp", "【玩家站起】房间号：" + r.Number + "，座位号：" + strconv.Itoa(int(o.Pos)) +
		"，玩家：" + o.Nickname + "，OutId :" +strconv.Itoa(int(o.OutId)))

	pos := o.Pos
	//todo 查询玩家是否在房间中，确认站起
	if o.IsGameing() {
		if r.Current == pos {
			o.SetAction(-1)
		}else {
			r.remain --
		}
	}
	//time.Sleep(time.Second)
	code := 1
	if r.leaveAndRecycleChips(o){
		code = 0
	}
	jsonStu := json2.Jsonmr(58, &protocol.StandUp{
		Code: code,
		Position: pos,
	})
	r.staticOccupants[o.Pos-1] = *o
	r.addObserve(o)
	r.Broadcast(jsonStu, true)

	//站起完毕，检查在场的游戏人数是否小于2，是的话，最后一人不用下注，直接后台 跟注，然后结束对局
	if r.remain < 2 {
		//轮询玩家列表，找出游戏中的玩家，帮她下注
		for i, o := range r.Occupants {
			if o != nil && o.IsGameing() {
				follow := r.Bet - o.Bet
				r.Occupants[i].SetAction(int32(follow))
			}
		}
	}


}

func (r *Room) Chat(m interface{}) {
	jsons := json2.Jsonmr(62, m)
	r.Broadcast(jsons, true)
}

//func (r *Room) ReqRound(i int) {
//	if r.IsRunning() {
//		switch i {
//		case Round2:
//			fmt.Println("Round2chan")
//			if r.waitAction {
//				r.reqRound2 <- i
//			}
//		case Round3:
//			fmt.Println("Round3chan")
//			if r.waitAction {
//				r.reqRound3 <- i
//			}
//		case Round4:
//			fmt.Println("Round4chan")
//			if r.waitAction {
//				r.reqRound4 <- i
//			}
//		case Result:
//			fmt.Println("Round2")
//			if r.waitAction {
//				r.reqResult <- i
//			}
//		}
//	}
//}